/*********************************************************************
/* Java Anything Implementation as universal Data Access Object
/*
/* Copyright (C) 2006 Stefan Tramm
/* 
/* This library is free software; you can redistribute it and/or
/* modify it under the terms of the GNU Lesser General Public
/* License as published by the Free Software Foundation; either
/* version 2.1 of the License, or (at your option) any later version.
/* 
/* This library is distributed in the hope that it will be useful,
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
/* Lesser General Public License for more details.
/* 
/* You should have received a copy of the GNU Lesser General Public
/* License along with this library; if not, write to the Free Software
/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
/* MA  02110-1301  USA
/********************************************************************/

import static any.Any.util;
import static any.functor.Functions.asProperties;
import static any.incubator.CreateAnyCreator.entry;
import static any.incubator.CreateAnyCreator.values;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.util.Properties;

import any.Any;


public class AnyDAOExample {

    public static void main (String args[]) {
    	Any res = null;
        System.out.println("AnyDAO example code");
        try {
            // Load the JDBC driver
            String driverName = "oracle.jdbc.OracleDriver";
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            System.out.println("Could not find the driver");
            return;
        }

        
        Properties info = util.give(values(entry("user", "scott"), entry("password","tiger")), asProperties());
        try {
            Connection con = DriverManager.getConnection("jdbc:oracle:thin:@silver.local:1521:playg", info); // place your own connection string here
            con.setAutoCommit(false);
            res = AnyDAO.query(con, "SELECT * FROM EMP");
            System.out.println(res);
            BigDecimal sum = BigDecimal.ZERO;
//            res.get("Data").give(fold(add(), asBigDecimal().withDefault(0)).select(hasKey("SAL")));
            for (int i = 0; i < res.get("Data").size(); i++) {
                sum = sum.add(res.get("Data").get(i).get("SAL").asBigDecimal(0));
            }
            System.out.println("Salary sum is "+sum.toString());
            res = AnyDAO.query(con, "select SAL from emp",
                new AnyDAO.Callback() {
                    private BigDecimal s;
                    public void init() {s = new BigDecimal(0);}
                    public Any finish(int rowCount) {return Any.create.any(s);} 
                    public void call(int rc, Any r) {
                        s = s.add(r.get("SAL").asBigDecimal(0));
                    }
                });
            System.out.println(res);
            testScott(con);

            con.rollback(); // play safe
            con.close();
        } catch (java.lang.Exception ex) {
            System.out.println("Some exception...");
            ex.printStackTrace();
        }           
    }
    
    private static void testScott(Connection con) {
//        Anything i = Anything.create(
//          "{" +
//              "/EMPNO 9999" +
//              "/ENAME \"Stefan\"" +
//              "/DEPTNO 20" +
//              "/HIREDATE Date \"2006-04-24 00:00:00.0\"" + 
//              "/JOB *" +
//          "}");
        // we can initialize i also in a different way...
    	Any i = Any.create.any();
    	i.put("EMPNO", 9999)
         .put("ENAME", "Stefan")
         .put("DEPTNO", 20)
         .put("HIREDATE", new Date(0)) // needs something nicer
         .put("JOB", null);  // null
    	System.out.println(i);
    	Any r = AnyDAO.insertRows(con, "EMP", i);
        System.out.println(i);
        i.put("HIREDATE", new Date(System.currentTimeMillis()));
        System.out.println(i);
        r = AnyDAO.statement(con, new String[] {
            "UPDATE EMP SET ENAME=?, HIREDATE=? WHERE EMPNO=?",
            "ENAME", "HIREDATE", "EMPNO"}, i); // Anything i contains the data
        System.out.println(i);
        
        // test bulk insert
        Timer t = new Timer();
        t.start();
        Any rows = Any.create.any();
        for (int c = 0; c < 1000; c++) {
            rows.get(c)
                .put("EMPNO", 8000+c)
                .put("ENAME", "bulk")
                .put("DEPTNO", 20)
                .put("HIREDATE", new Date(System.currentTimeMillis()));
        }
        t.stop();
        System.out.println("Creation time " + t.getTime());
        r = AnyDAO.insertRows(con, "EMP", rows);
        System.out.println(r);
    }
}
